home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The X-Philes (2nd Revision)
/
The X-Philes Number 1 (1995).iso
/
xphiles
/
hp48hor2
/
rpl489.doc
< prev
next >
Wrap
Text File
|
1995-03-31
|
66KB
|
1,848 lines
Magic48ges presents:
ûûûûû ûûûûû û û ûûû
û û û û û ûû û û
û û û û û û û û û
ûûûû ûûûû û û û ûûû
û û û û ûûûûû û û
û û û û û û û
û û û ûûûû û ûûû
A SYSTEM-RPL DEVELOPMENT TOOLKIT FOR THE HP48
Version 2.02
(c) 1993 by Detlef Mueller & Raymond Hellstern, Magic48ges
CONTENTS
íííííííí
1. Introduction
1.1 Copyrights & Acknowledgements
1.2 The RPL48 Toolkit
1.3 Requirements & Installation Instructions
1.4 Abbreviations
2. <-RPL-> Library
2.1 Overview
2.2 The System-RPL Compiler/Decompiler
2.3 The Saturn Assembler/Disassembler
2.3.1 The Assembler Parameter Field Parser
2.4 The Reference Table
2.5 Command Reference
2.6 Hooks
2.7 Things to Notice
3. <-LIB-> Library
3.1 Overview
3.2 Control Variables
3.3 Command Reference
3.4 Things to Notice
Appendix A - Quick Reference Guides
A.1 <-RPL->
A.1.1 Commands
A.1.2 Flag Usage
A.1.3 Error Messages
A.2 <-LIB->
A.2.1 Commands
A.2.2 Flag Usage
A.2.3 Error Messages
Appendix B - A ->COD Example
Appendix C - Ordering Information
1. Introduction
ííííííííííííííí
1.1 Copyrights & Acknowledgements
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
All files of the RPL48 toolkit are copyrighted (c) by Detlef Mueller and
Raymond Hellstern - Magic48ges, 1991-1993 - unless otherwise noted.
The RPL48 package is distributed in the hope that it will be useful, but
RPL48 is provided 'as is,' and is subject to change without notice.
D. Mueller and R. Hellstern make no warranty of any kind with regard to
the software or documentation, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose.
D. Mueller and R.Hellstern shall not be liable for any error or for
incidental or consequential damages in connection with the furnishing,
performance, or use of this software and documentation.
This version of RPL48 is a GiftWare release. You may use it as long as you
like without registration, but only for developing non-commercial software.
Permission to copy the whole, unmodified RPL48 package is granted provided
that the copies are not made or distributed for resale (excepting nominal
copying fees). If you want to get your own, brand new version, and for further
information, please refer to Appendix C.
It should be impossible to crash your '48 by using RPL48, but be warned:
no software is bug free !
We would like to thank the following people for their support:
Wlodek Mier-Jedrzejowicz for presenting RPL48 to the world.
Rick Grevelle for the HACKIT library, the ->DIR command of
<-LIB->, the base of the sys-stack, many
suggestions, exiting talks and for sending
us an HP48GX.
Mika Heiskanen for beta testing, lots of suggestions, MKROM,
DEBUG, and for a great performance enhancement
of the D->LIB and L->DIR commands.
Douglas R. Cannon for beta testing, lots of suggestions, and
for reviewing this document.
Joseph K. Horn for beta testing and suggestions, the `HP 48
Resource Allocation Guideline; Library ID's`,
SORTLS and for maintaining the '48 GDs.
Carlos Ferraro for beta testing and his friendship.
Simone Rapisarda for beta testing and many suggestions.
Fatri Mohamed,
Romain Desplats,
Georg Hoppen for suggestions and beta testing.
James H. Cloos,
Steve VanDevender,
Chris Maksymiak for suggestions.
Jeoff Krontz, for suggestions, beta testing, getting another
GX for Raymond, exiting talks, and..
Chris Spell ..for maintaining the '48 archive at
seq.uncwil.edu and for moderating
comp.sources.hp48.
Dennis York for the kindly permission to publish the BNF
parser generator example.
W.C.Wickes & HP Corvallis for the '48 and the RPL tools.
1.2 The RPL48 Toolkit
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
The RPL48 Toolkit provides more than 50 powerful commands to aid system RPL
and assembler programming and library development on a HP48. It consists of
three parts:
* library 1234, <-RPL->:5.00 - contains a sys-RPL compiler/decompiler
and Saturn assembler/disassembler.
* library 1221, <-LIB->:2.0 - contains a library creator/splitter and
many commands for handling libraries and un-/supported objects.
* a reference table which contains address/name pairs of ROM entry
points.
The main commands of RPL48 are modeled after the MesS-DOS programs RPLCOMP.
EXE, SASM.EXE and USRLIB.EXE which are provided by HP in the self extracting
archive TOOLS.EXE (available on several ftp sites and GD#4). This document
describes the interface to RPL48; it is not a sys-RPL or Saturn assembler
manual. Please refer to RPLMAN.DOC, RPLCOMP.DOC, USRLIB.DOC and SASM.DOC
(all contained in TOOLS.EXE) for learning and/or reference purposes.
We assume that you are familar with the fundamentals of sys-RPL, Saturn
assembly and libraries.
1.3 Requirements & Installation Instructions
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
RPL48 should work on ROM versions A-M HP48 - it's tested on rev A, E, L, M
machines by the authors, and it's reported to run also on rev D and J.
The <-RPL-> library is compiled to a fixed address; it MUST be stored in an
independent (FREEd) port (ie. it only works on a SX or GX), on a SX this can
be either port 1 or 2, on a GX this must be port 1 !
Because the whole RPL48 kit requires ~60kb of memory (including a reference
table made from the latest entries released by HP) it is recommended to store
it into a 128k RAM card. The <-LIB-> library was developed using the standard
methods, it can be stored and used in port 0 on any HP48; on a GX it's
limited to the ports 0 and 1, and must not be installed in the ports 2-33.
For a complete installation of RPL48 it is neccessary that you have plugged
in a 128k RAM card (which must have ~60kb free space) in either port 1 or 2
of your SX, port 1 of your GX; the card must be set to R/W. Proceed as
follows:
a) remove all files of an earlier version
b) merge the port
c) set up RPL.TAB on your computer by renaming one of the two shipped
reference tables or by creating an own one (see section '2.4 The
Reference Table')
d) download RPL.TAB, LIB.LIB and RPL.LIB
e) recall RPL.TAB to the stack, purge RPL.TAB and store it as a backup
object named RPL.TAB (case sensitive !) into port 0 (:0:RPL.TAB STO)
f) recall the two libraries, purge the variables containing the original
copies and store the libraries into port 0 (two times 0 STO)
g) free the port, make sure that :0:1234 is the 1st entry of the list
in level 2 for the FREE command ! (you can use 0 PVARS DROP to
generate the base list)
h) warmstart the '48 (power cycle it, or press [ON]-[C])
As mentioned, <-RPL-> is compiled to an absolute address. Its config code
takes care of the address the library is stored at. On an SX, if neccessary,
the base addresses of the ports are swapped and an additional warmstart
is initiated automatically while executing the first warmstart after
installation. If the config code recognizes that it is impossible to change
to the correct address (ie. the library is stored in port 0, not the 1st
object of port 1 or 2 on a SX, or not the 1st object of port 1 on a GX), the
autoattach to the home directory is supressed and no (c)-message and no beeps
are generated. If the library did not attach itself, make sure it becomes the
1st object of the desired port and execute a warmstart again.
If you have installed an HP41 emulator card, <-RPL-> does not install because
the emulator uses a similar sheme to install itself to the same address (it
is also an absolute library) -- just remove the card.
The <-RPL-> and the <-LIB-> libraries are not self-modifing - you can write
protect the card containing the libraries.
1.4 Abbreviations
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
LID - library id; a number in the range 0..2047, part of any library, It
is used by the HP firmware to identify libraries while resolving
commands, messages etc.
| - used in stack diagrams for 'or'
Abbreviations denoting objects:
ob object of any type
xlib named or unnamed library command
:x:y tagged object - tag x, ob y
prg program (secondary)
bak backup
dir directory
alg algebraic
lib library
libdta library data
meta(t) meta object, obn .. ob1 %n, all ob's are of the same type t
All other abbreviations are defined in RPLMAN.DOC (like %, # etc.).
2. <-RPL-> Library
íííííííííííííííííí
2.1 Overview
ÄÄÄÄÄÄÄÄÄÄÄÄ
<-RPL-> contains 17 commands, including a sys-RPL compiler (->RPL), a sys-RPL
decompiler (RPL->), a Saturn assembler (->COD), a Saturn disassembler (COD->)
a RPL.TAB browser (EC) and a medium font sys-stack environment (4/5/7).
2.2 The System-RPL Compiler/Decompiler
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
The compiler is a simple token based one pass LR compiler and implements a
grammatical subset of RPLCOMP.EXE. It accepts string objects containing a
token sequence, seperated by whitespace (NL,CR,Space,TAB etc.), as input.
The output of the decompiler can be used as input for the compiler or (with
minor modifications) as input for RPLCOMP.EXE.
While ->RPL is compiling a string, it recognizes certain words and generates
appropriate code for them. All other words are assumed to be the labels of
objects in the runstream and are emitted simply as 5-nibble constants - the
reference table (see below) and the assembler symbol table are searched to
resolve the appropriate 5-nibble addresses. If an entry can't be found in one
of the tables and its 1st chararcter is a 'x', then ->RPL will try to resolve
the word without the leading 'x' as a built-in word (e.g. for 'xDROP' the
address #1FBD8 would be generated).
If the currently processed token isn't resolvable by ->RPL as an object,
entry, or built-in word, it is passed to the user-RPL compiler, palparse.
If the result is an ID or prg, an error will be generated. If the token is
parsed to a %, it will be converted to a # (eg. "12345" ->RPL --> <3039h>
(negative values are mapped to 0 and fractional parts are ignored)); any
other valid object is simply added to the runstream (eg. [[1,2][3,4]] (F(.))
inserts a 2*2 array of %).
The following words are recognized by ->RPL or generated by RPL->:
LAM <id> (1)
DOLAM object whose name is specified by <id>.
ID <id> (1)
DOIDNT object whose name is specified by <id>. 0-IDs aren't supported by
->RPL.
TAG <id> <ob>
DOTAG object whose tag is specified by <id> and whose object is given
by <ob>.
$ "string" (1)
DOCSTR object with the contents contained between the quotes.
CHR <char> (1)
DOCHAR object with the specified character.
# <hex> (3)
#<hex> (3)
DOBINT object whose body is the number specified in hex.
% <real>
DOREAL object with the specified floating-point number.
%% <extended real>
DOEREL object with the specified floating-point number. The number is
parsed with % resolution.
C% <real> <real>
DOCMP object with the specified floating-point numbers.
C%% <extended real> <extended real>
DOECMP object with the specified floating-point numbers. The numbers are
parsed with % resolution.
PTR <address in hex> (2,5)
Inserts the specified address as a runstream pointer-obj.
ROMPTR <LID> <rom word>
DOROMP obj whose body will contain the two 3-digit hex numbers.
HXS <length in hex> <hstring>
GROB <length in hex> <hstring>
CODE <length in hex> <hstring> (2)
ARRY <length in hex> <hstring> (2)
LNKARRY <length in hex> <hstring> (2)
LIBRARY <length in hex> <hstring> (2)
BACKUP <length in hex> <hstring> (2)
LIBDAT <length in hex> <hstring> (2)
EXT1 <length in hex> <hstring> (2,4)
EXT2 <length in hex> <hstring> (2)
EXT3 <length in hex> <hstring> (2)
EXT4 <length in hex> <hstring> (2)
Specified object whose body is made from the specified hex-string.
Zero-length obj's aren't supported by ->RPL.
ACPTR <data address> <access routine address> (2,4)
DOACPTR object, whose data and access routine addresses are built from
the two specified hex numbers.
NIBB <length in hex> <hstring> (2)
Adds the binary form of the specified hex string to the runstream, eg.
NIBB 7 84E2000 creates a 0-ID.
CODE <assembler source ..> ENDCODE
CODE object, the assembler is called to assemble the body.
ASSEMBLE <assembler source ..> RPL
The assembler is called to assemble the inline code.
INCLUDE <name>
The accessable path is searched for a variable with the name <name>. Its
contents must be a compilable string and may contain further INCLUDE
statements. The resulting code is inserted at the position of the INCLUDE
statement.
INCLOB <name> (2)
The accessable path is searched for a variable with the name <name>. Its
recalled contents are inserted at the position of the INCLOB statement.
The following words create runstream pointer obj's:
UNIT DOEXT - Unit start
SYMBOL 02AB8 - Symbolic start
:: DOCOL - Program start
{ DOLIST - List start
} SEMI - List terminator
; SEMI - Program, UNIT or SYMBOL terminator
Text surrounded by ' (' and ') ' is ignored by ->RPL.
Before you start compiling your own objects, play with the decompiler to
get some examples of the syntax definitions, eg. try { + } 1 GET RPL-> to
decompile 'x+'.
->RPL will automatically add SEMIs at the end of a compiled object to close
any open composite object, ie. compiling ":: 1" will create :: ONE ;
Note (1)
Character substitution is supported via '\xxx' in strings, IDs, LAMs and
CHRs using the internal routine which does the tranlsation for TRANSIO,
code 3 (see the '48 manual for a complete description). You must use
'\034' to insert doublequotes (") into strings.
RPL-> generates (") within strings, not \034.
Note (2)
These statements are not supported by RPLCOMP.EXE.
Note (3)
->RPL accepts BINTS in one of the following form:
# xxx - allways compiled to BINT objects
#xxx - searches the ROM for a BINT with the appropriate value, if
found a pointer to it is generated instead of a BINT object
xxx - real numbers are COERCED and then handled like #xxx
Note (4)
ACPTR and EXT1 obj's do have the same prologue addresses but are defined
differently, the former is a GX only obj, the latter an SX only obj.
->RPL won't allow you to compile a EXT1 obj on a GX and vice versa. RPL->
can only handle ACPTR !
Note (5)
If you want to recompile a source generated by RPL->, you must manually
replace all PTR 12345 statements by
ASSEMBLE
CON(5) #12345
RPL
2.3 The Saturn Assembler/Disassembler
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
The assembler defines a subset of SASM.EXE written by Nathan Zelle. You can
use it 'stand-alone' or in conjunction with the RPL compiler ->RPL. It's a
2-pass assembler.
The input string should be plain ASCII (with blanks and/or TAB's) generated
on a PC or the '48 itself.
It is 'free format' which means that no column counting is required, except
that labels MUST begin in the first coloumn of a line.
If a line consists only of a comment, an '*' MUST be in column 1. Empty lines
are ignored.
The general line structure is: "<label> [<mnemonic> [<parameter>] [<comment>]]"
or "* <comment>"; the fields are seperated by blanks or TABs.
Most parameters can be symbolic (eg. " GOVLNG (=SAVPTR)+45*3" is valid).
The assembler supports conditional assembling as well as defining equates via
"Label EQU expression". Please refer to SASM.DOC for more details.
You can call global entry points if a reference table is installed.
A predefined standard macro named LOOP is also included. If entered in the
mnemonic field it will be assembled to " GOVLNG =Loop", an address which
simply does
=Loop A=DAT0 A
D0=D0+ 5
PC=(A)
If the assembler source don't contain any code, the 2nd pass is skiped to
speed up RPL define like constructs - eg. a directory may hold along with
the source strings a variable HEADER:
(HEADER)
ASSEMBLE
@a EQU =1GETLAM
!a EQU =1PUTLAM
@b EQU =2GETLAM
!b EQU =2GETLAM
nr EQU =TWO
RPL
which may be included by a source like:
(xyz - just a program)
INCLUDE HEADER
::
CKN
DUP nr #<> case SETSIZEERR
' NULLLAM nr NDUPN {}N BIND
@a @b 2DUP EQUAL ?SWAP
!b !a
(...etc...)
ABND
;
2.3.1 The Assembler Parameter Field Parser
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Parameter fields are parsed by an expression parser that is defined as
follows:
expr : expr op1 term | term
term : term op2 fact | fact
fact : '(' expr ')' | op3 fact | '(' '=' entry ')' | '(' symbol ')' | num
op1 : '+' | '-' | '!' | '|' | '^'
op2 : '*' | '/' | ':'
op3 : '-' | '"'
num : real-number | '#' hxs-number
entry : label of RPL.TAB
symbol : label of the assembler symbol table
op action
ÄÄ ÄÄÄÄÄÄ
* multiply
/ divide
: modulo
" ones complement
- subtract / twos complement
+ add
! bit AND
| bit OR
^ bit XOR
A complete expr must not contain whitespace chars. If an expression consists
only of a '#' number, an entry or a symbol, the parenteses aren't neccessary
(eg. @n EQU =1GETLAM ). Real numbers are converted internally to HXS numbers,
the accuracy is 64 bit. Parsing real numbers and hex numbers is done by the
'48 internal real/hex parser. The expr/term/fact parser uses the solver
token type table.
Expressions of EQU parameter fields must resolve to the requested number
during the 1st assembler pass; they are ignored in the 2nd pass.
2.4 The Reference Table
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
RPL->, ->RPL, COD->, ->COD, EC, E<->A and 4/5/7 are looking for a reference
table named RPL.TAB which is used to resolve names and addresses of ROM
entry points. It may be stored in a variable, as a backup object in any port
or as a library command. If RPL.TAB exists, its recalled contents will be
evaluated and if the result is a string starting with '\000\010' it will be
used as a reference table. It is recommended to use one of the two tables
shipped with RPL48; they are made using the latest entries lists released by
HP as database - double named entries are removed and a few user-RPL names
are added to avoid conflicts when de/compiling different '->', '>>', 'END'
(user-RPL) words.
For generating your own tables, use GENTAB.C, also shipped with RPL48.
The following example (HP terminology) outlines the structure of a reference
table:
ASSEMBLE
CON(5) =DOCSTR String prologue
REL(5) TabEnd Length field
NIBASC '\00\n' Reference table identifier
* A hash table, for each char from ' ' - DEL
* a 5-nib offset into the table
CON(5) 0 ' ' entry, empty
REL(5) _!_ relativ offset to words starting with '!'
CON(5) 0 '"' entry, empty
* ... '#' - 'C'
REL(5) _D_ 'D' entry
* ... 'E' - '}'
CON(5) 0 '~' entry, empty
CON(5) TabEnd DEL entry, always TabEnd
_!_
CON(6) #9623A0
NIBASC `!!append$`
* ...
_D_
* úÄÄÄÄÄÄÄ Length of the label in bytes.
* 3 A label can't be > 15 chars in size.
* 3úââââÄÄ Address associated to the label, here 074E4
* 333333
CON(6) #6074E4 Address/length field of the following
NIBASC 'DOBIND' Label
TabEnd
RPL
2.5 Command Reference
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
RPL-> ( ob --> $ )
Decompiles an object into a string. The string can be used as input for
->RPL without modifications (most times).
->RPL ( $ --> ob )
Compiles the input string to an object.
DCADR ( hxs[adr] --> $ hxs[adr]' )
Decompiles the object referenced by the address adr to a string in
level 2 and increment the address by the object size.
COD-> ( code --> $ )
Disassembles a code object, generates HP styled mnemonics. The reference
table is searched for addresses of GO and Dx=(5) mnemonics. The string
can be used as input for ->COD without modifications (most times).
->COD ( $ --> code LibDat )
Assembles a code object. LibDat is the compressed form of a cross
reference listing, use SYM-> (see below) for decompression.
->OB ( hxs[adr] --> ob )
( #adr --> ob )
( XLIB --> ob )
( ob --> ob' )
Input Action
ÄÄÄÄÄ ÄÄÄÄÄÄ
hxs Build a pointer, pointing to the address given by the value
of hxs[adr].
# Same as for hxs, except if the value of # points to a valid
ob in the hidden ROM; in this case the object is copied into
TEMPOB. Eg. "# 72000" ->RPL ->OB returns the message table
of the internal library 0.
On a GX, passing a # is the same as passing a HXS.
XLIB Does a rompointer recall.
ob Unconditionally TOTEMPOB.
DAN ( hxs[adr] %n --> $1 .. $n hxs[adr]' )
Disassembles n instructions starting at address hxs[adr].
DA1 ( hxs[adr] --> $ hxs[adr]' )
Disassembles the instruction at address hxs[adr].
DAXY ( hxs[start] hxs[end] --> $ )
Disassembles until the actual adr. is > hxs[end], starting at address
hxs[start].
SYM-> ( LibDat --> $ )
Converts the cross reference table produced by ->COD into a string.
$-> ( $ --> ob )
Converts a hex-dump to an object.
->$ ( ob --> $ )
Generates a hex-dump of an object.
EC ( --> ? )
Entries Catalog - the reference table browser. Errors if no RPL.TAB
can be found.
When starting EC the first time, it'll create the variable ECpar in
the HOME directory. It contains a HXS that is used by EC as a lookup
table into RPL.TAB; you may store the variable into a port (like
RPL.TAB). Any time you install a new reference table it is neccessary
to purge ECpar !
The main display of EC shows eight entries, one per line. Each line shows
the name and the addresses of an entry, a 'm' behind the address marks non
RPL entries (ie. ML entries). These words are probably for use within
assembly only. One line is inversed, showing the current position of
the cursor bar which can be moved by the UP/DOWN arrows.
Active keys in the main display of EC:
Unshifted:
UP - move scroll bar up one word
DOWN - move scroll bar down one word
ENTER - push highlighted word as $ onto the stack. If EC is launched
from a command/edit line, ENTER coppies the word into the
editline starting at the current cursor position
NXT - scan for next occurence of the SCAN word.
ON - exit EC or cancel sub-action
Rightshifted:
ENTER - in case no editline exists, the current word is copied into a
newly opened editline
UP - move to first entry
ON - turn off
Menu keys:
PG|^ - page up
PG|v - page down
SCAN - prompts for a $ to search, ENTER starts searching. If EC is
launched from a command/edit line, the prompt looks a bit
suspicious, but its functionality is the same
A-Z - try it
A->ST - push the address of the current word onto the stack. If EC
is launched from a command/edit line, the A->ST key changes
to the ABOUT key.
HELP - provides two pages of help on keys
For use of EC within a normal edit line, append the following list to
your CST variable and launch EC with CST EC:
{ $ "EC" :: TakeOver ROMPTR 4D2 C (EC) ; }
E<->A ( hxs[adr] | $name --> $name | hxs[adr] )
Searches the reference table for a name or address of a given address or
name. Errors if the label or address can't be resolved.
RPLtab ( --> $ )
Tries to recall the ref. table via RPL.TAB. If no table is found, a
zero-length string is returned.
4/5/7 ( --> )
Starts the medium font sys-stack display in five line mode. Pressing
4/5/7 in five line mode switches to seven line mode, in seven line mode
the sys-stack is canceled.
If you have flag 61 set, the commandline changes to sys-RPL mode, and
the i-stack allows you to edit objects in sys-RPL syntax when pressing
the EDIT menu key.
The following keys are redefined while the 5/7 stack is active:
- pressing the up arrow without an active edit/commandline starts a
5/7 level interactive sys-RPL stack
- pressing the down arrow without an active edit/commandline starts
editing the object of stack level one in sys-RPL syntax, if flag
61 is set.
- pressing ENTER to terminate a command line compiles it using the
internal ->RPL, if flag 61 is set.
YOU MUST NOT MOVE THE <-RPL-> LIBRARY WHILE 4/5/7 IS ACTIVE !!
(ie. DON'T MERGE THE PORT WHERE <-RPL-> IS STORED WITH AN ACTIVE 4/5/7 !!)
Clear flag 62 to quit 4/5/7 if you wan't to purge/move <-RPL->.
CC ( --> ? )
Character set Catalog. CC displays a map of 128 characters in the small
font along with some more information for the highlighted char. You can
move through the map using the cursor keys. If you hold down one of the
cursor keys, it will repeat until you release. The ON-key exits the
program, RIGHT-ON turns the calc off and ENTER fetches the char number
(tagged with the char) to the stack.
There are three menu keys available:
SWAP - swaps between the upper/lower half of the char set
BIN - toggles the char code display from real/hex to binary and back
EXIT - leaves CC
If you launch CC within an active editline (eg. via the CST menu), ENTER
will copy the highlighted character into the editline to the current
cursor position. For use of CC within a normal edit line, append the
following list to your CST variable and launch CC with CST CC:
{ $ "CC" :: TakeOver ROMPTR 4D2 10 (CC) ; }
2.7 Hooks
ÄÄÄÄÄÄÄÄÄ
There are a few user hooks in <-RPL->, each an unnamed ROMPTR:
ROMPTR 4D2 13 ( --> )
Switches to ADISP and displays a 5/7 level sys-RPL stack.
ROMPTR 4D2 14 ( --> )
Errors if <-RPL-> isn't ATTACHed to the HOME directory.
ROMPTR 4D2 15 ( ob --> $ )
Decompiles an object in quiet mode, eg. for editing.
ROMPTR 4D2 16 ( $ --> )
Compiles a string in quiet mode, eg. after editing.
Note: no stack checks are done by these routines !
2.7 Things to Notice
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
->RPL maintains a global assembler symbol table while compiling an object,
ie. it is possible to jump backward from a code object to a previous one:
::
CODE
Lp LOOP
ENDCODE
CODE
GOTO lp
ENDCODE
;
(Note: in the current version of <-RPL-> this seems not to work, I'm bug
hunting... Detlef)
->RPL tries to resolve a token in the following order:
1. check for atomic object (eg. %, # et c.)
2. search reference table
3. search symbol table
4. check for #<hex-no>
5. check for user-RPL word
6. check for user-RPL object
The search of the symbol table enables the programmer to use DEFINE like
constructs:
::
ASSEMBLE
@val EQU =1GETLAM
!val EQU =1PUTLAM
RPL
ONE 1LAMBIND
@val #1+ !val
1GETABND
;
3. <-LIB->
íííííííííí
3.1 Overview
ÄÄÄÄÄÄÄÄÄÄÄÄ
<-LIB-> contains 39 commands, including a library maker (D->LIB), a library
splitter (L->DIR), commands to handle any sort of composite objects and
commands to manage libraries.
Libraries are very useful objects to extend the command set of a '48 in a
'native' manner, but unfortunately library creation is not supported by the
'48 firmware. The HP tools package contains the program USRLIB.EXE, which
provides library creation on a PC; if you want to move your most often used
programs into a library (because of easier handling and to keep your VARs
area clean), you have to collect them into a subdirectory, add a few control
variables, transfer the directory in binary form to a PC, run USRLIB.EXE on
it, and transfer the created library back to your '48, where you can install
and test the library.
<-LIB-> provides the command D->LIB that works on the currently active
directory, allowing you to create a library from this directory on the '48
itself - no transfers, no PC, and no USRLIB.EXE are required.
The input directory stucture of D->LIB is very similar to the directory
structure required by USRLIB.EXE, thus existing USRLIB.EXE input can be
used for a library creation with minor changes (the difference is the
format of the $MESSAGE control variable, see below).
3.2 Control Variables
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
The library creation process is controlled by some variables with reserved
names and only the current directory is searched for their presence (note:
multiple occurences of these names are ignored, only the contents of the
first one found in the current directory is used for the library creation
process):
$ROMID
Must contain a real or binary number representing the LID that is to
be given to the library. The LID must be in the range 0..2047. Negative
real numbers are mapped to 0.
This is the only control variable that MUST exist in the current
directory !
$TITLE
Should contain a character string to be used as the name of the library
(note: any other object is converted to a string). The first few
characters of the name are displayed in the LIBRARY menu label
associated to the library, the first 22 characters are displayed by
pressing REVIEW in the LIBRARY menu. If $TITLE is absent or contains an
empty string, no title is generated and the resulting library doesn't
have a menu label in the LIBRARY menu (note: you can switch to the
library's command menu by executing %LID MENU, even if the library
doesn't have a name or is not attached).
$CONFIG
Must contain a program to be executed at configuration time.
The configuration code can generally NOT be written in user-RPL, but
simple programs such as \<< 123 ATTACH \>> are Ok - more complicated
programs should take care to leave the stack unchanged, and be sure
NOT TO ERROR ! An error in a configuration program will cause a warmstart;
the configuration code is called again during the startup process,
producing a new error etc. If you are accidentally trapped by this, you
must clear your memory to remove the faulty library !
$MESSAGE
Must contain a list of strings to be combined into a message table (note:
any other objects are converted to strings). The message numbers
correspond to the list positions. In user-RPL you can generate errors
with your own messages in the following manner:
#32001h DOERR
33333
333àáÄÄ Message number (here 1)
àááÄÄÄÄ LID (here #320h = 800)
In sys-RPL you can use
# 32001 ERROROUT
In this example an error is generated, using the first message from the
message table of a library with the LID 800.
Note: The message list structure is NOT compatible to USRLIB.EXE.
$VISIBLE
Must contain a list of names of variables to be converted to user-
accessible, named library commands. By default, all variables will be
translated to named library commands. When the $VISIBLE list is present,
only the names in this list are included in the library hash table. An
empty list is Ok, meaning that no hash table is generated.
$HIDDEN
Must contain a list of names of variables that are to be converted to
unnamed objects in the library. When the $HIDDEN list is present, those
names listed are not entered in the library hash table. If both $VISIBLE
and $HIDDEN are present, only $HIDDEN will be used.
Note: all visible commands appear as labeled softkeys in the menu
associated to the library, all hidden commands are not, and there is no
way to access them from user scope.
$VARS
Must contain a list of variables that should remain RAM-based - i.e. the
objects of the variables listed in $VARS are not included in the library
and no XLIB pointers are made to substitute their names. All other
variables of the current directory are included in the library.
Note: You should add all subdirectory names of the current directory to
the list.
$ROMID must exist in the current directory, all other control variables are
optional - eg. you can generate libraries containing only a configuration
program or a message table. All control variables are internally handled by
D->LIB to be $VARS and can't be accessed from within the library commands.
3.4 Command Reference
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
D->LIB ( --> lib )
Dir to lib; assembles a library from the objects of the current directory.
The creation process is controlled by a few variables with reserved names
(see '3.3 Control Variables').
If you set flag -13 before running D->LIB, it will switch off the screen
while working (for saving time and batteries).
L->DIR ( %LID --> dir )
( xlib --> ob )
Lib to dir; if the argument is a LID then L->DIR assembles a directory
containing all commands of this library as variables. The neccessary
control variables (see 3.3) are also generated. D->LIB may be used to
recreate the library.
If the argument is an XLIB, then L->DIR recalls its object from the
associated library onto the stack.
If you set flag -13 before running L->DIR on a library, it will switch
off the screen while working.
Note: You cannot use L->DIR to split <-LIB->, this should prevent users
from a memory lost. If you are familiar with the internals of your '48,
use 'ROMPTR@' (or ->OB of <-RPL->) to extract single routines from
<-LIB->, but beware of starting the routines in RAM, most of them will
crash your calc when running alone !
MCFG ( --> )
Make config; stores a configuration program into a variable named
'$CONFIG' into the current directory. This configuration program will
attach the generated library to the home directory at warmstarts (ON-C
etc.).
'$ROMID' must exist in the current directory.
ML->D ( --> prg )
Generates a program with the following interface:
( {} --> libdta )
The list can contain anything. The program checks for argument count and
type and may error with:
#201 - To Few Arguments - nothing on the stack
#202 - Bad Argument Type - not a list on the stack
'$ROMID' must exist in the current directory.
MD->L ( --> prg )
Generates a program with the following interface:
( libdta --> {} )
The program checks for argument count, type and correct LID and may error
with:
#201 - To Few Arguments - nothing on the stack
#202 - Bad Argument Type - no library data on the stack
#203 - Bad Argument Value - the libdta wasn't created by this lib
'$ROMID' must exist in the current directory.
Note: Store the programs generated by ML->D and MD->L into variables in
your source directory and use them as an interface to generate/resolve
data associated to the resulting library.
OB-> ( prg --> ob1 .. obn %n )
( xlib --> %LID %objno )
( arry --> ob1 .. obn { %di .. %d1 } )
( alg --> ob1 .. obn %n )
( dir --> ob1 id .. obn id %n )
( id --> $ )
( libdta --> {} %LID )
( bak --> ob id )
( id --> $ )
( ob --> dispatch to OBJ-> )
OB-> is an extension to the built-in OBJ->, supporting system level
objects.
->DIR ( ob1 id1 .. obn idn %n --> dir )
->PRG ( ob1 .. obn %n --> prg )
->XLIB ( %LID %cmdno --> xlib )
( #LID #cmdno --> xlib )
->ARR ( ob1 .. obn %n --> arry )
( ob1 .. obn { %di .. %d1 } --> arry )
->ALG ( ob1 .. obn %n --> prg )
->LD ( {} %LID --> libdta )
->BAK ( ob id --> bak )
->ID ( $ --> id )
Functions to reverse OB->.
About ->ARR:
Generates arrays of any type and any dimension (eg. a four dimensional
array of libraries :-).
%di * .. * %d1 must be = n, ob1 .. obn must be of the same type.
All possible parameter errors are trapped.
ADRp ( ob --> ob #addr )
Get address of ob.
Note: The data stack is a stack of pointers to objects. ADRp simply
returns the value from the top element (about the 'p', see 'LIBp' below).
$romid
$visible
$title
$config
$vars
$hidden
$message ( --> '$XXX' )
These commands just put a control variable name onto the stack.
LBCRC ( lib --> lib' )
( bak --> bak' )
Recalculates the CRC of a library or backup, useful if you have patched
it because modifying the body of a library or backup invalidates the CRC
included at the end of the body.
RNLIB ( lib $ --> lib' )
Renames a library, ie. changes title.
CHLID ( lib % --> lib' )
Change LID; this program allows you to change the LID of a library if
it's not splittable.
Note: Most time a LID is also hardcoded in the config code - this can
generally not be changed by CHLID. You have to attach the library manually
after a warmstart. Also any library has its LID coded in a field above
any visible command (the error handling system identifies the command
that caused an error using this field (the sys-RPL commands 'CKn' copies
this values to the appropriate location)). These fields are not changed
by CHLID (yet).
RHASH ( %LID --> hxs )
Recall hash table; get a pointer to the hash table of a library.
RLINK ( %LID --> hxs )
Recall link table; get a pointer to the link table of a library.
RCFG ( %LID --> ob )
Recall config code; get a pointer to the config code of a library.
RMSG ( %LID --> arry )
Recall message table; get a pointer to the message table of a library.
RTITLE ( %LID --> $ )
Recall title; get the name of a library.
Note: RHASH, RLINK, RCFG, RMSG and RTITLE don't error if the library
associated to %LID didn't contain the requested item, they leave the
stack unchanged in that case.
RPORT ( %port --> ob1 .. obn )
Recalls pointers to all objects of a given port (0/1/2 - 3-33 on a GX)
onto the stack, ignoring the R/W status of that port.
RLIB ( :%port:%LID --> lib )
( %LID --> libn %portn ... )
Recall lib; the 1st case recalls a library from a given port, the 2nd
case searches ports 0,1,2 (followed by ports 3-33 on a GX) for libraries
with %LID, returning all found libraries and the port numbers where
they're stored.
Note: On a SX this command actually returns pointer to libraries (like
RPORT), if you recall a lib and try to purge it while it's on the stack,
you'll get a 'Object in use' error. Execute NEWOB or store it into a
variable first.
PGLIB ( :%port:%LID --> )
( %LID --> )
Purge lib; the 1st case works like :%port:%LID PURGE, in the 2nd case the
ports are searched in order 0,1,2 (followed by ports 3-33 on a GX) for an
active library with %LID. The difference to PURGE: if the library is
attached to the home directory, it's detached before purging. On a SX:
Also if there is an inactive library with the same LID in any other port,
it becomes active and is attached to the HOME directory (if flag 5 is
set, its config code is executed - see STLIB below).
STLIB ( lib %port --> )
Store lib into port; there're a few differences to STO:
- The library is installed full; a warmstart isn't neccessary
and thus not initiated at the next power cycle. All warmstart
volatile variables (stack, PICT) remains intact.
- The library last stored is visible to the '48 (in case of
having a library with the same LID installed in another port).
- If flag 5 is clear, the library is attached simply to the
home directory.
- If flag 5 is set, the config code of the library is executed
under warmstart conditions. Usefull for testing a config code.
Note: This command is currently disabled on a GX !
ACLIB ( :%port:%LID --> )
Activate library. You can install libraries with the same LID in different
ports, but only one will be visible to the '48 at the time. During
warmstarts the ports are searched in order 2,1,0 (most cases), ie. the
library stored in the port with the highest number will be active.
ACLIB allows you to switch to any other library with the same LID at
runtime, the effect is immidiate. ACLIB 1st detaches the LID from HOME,
sets the new priority and than a) attaches the LID to HOME again if flag
5 is clear, or b) runs the library config code if flag 5 is set (see STLIB
above).
Note: This command is currently disabled on a GX !
LIBp ( %LID --> $ )
Returns a detailed layout of a library. The map starts with the title (if
exist), followed by the 1st and last address of the lib and the LID. The
remainder lists the contents of the lib, one line of information for each
XLIB entry. Structure of a line:
1st last xn name typ
333 3333 33 3333 àááÄ Type of the object
333 3333 33 àáááÄÄÄÄÄÄ Name of the object (if it's a visible cmd)
333 3333 àáÄÄÄÄÄÄÄÄÄÄÄ XLIB number of the object
333 àáááÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Last relative address of the object
àááÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Offset to startaddr. of the object
The list is sorted by offset. Try 1221 LIBp or 2 LIBp.
Note: If you find unexpected 'holes' between two XLIBs (> 10 nibbs) or
XLIBs embedded in other XLIBS, the library wasn't generated using
USRLIB.EXE or D->LIB; do not use D->LIB for recreating it because the
'holes' can hold essential data..
Note: This command is currently disabled on a GX !
INSTp ( --> { %LIDn .. %LID1 } )
Returns a list of all libraries attached to the current directory, { } if
none.
Note: You can PURGE libraries even if they are attached to a subdirectory.
INSTp can be used to find such zombie references.
LIBSp ( --> { %LID1 .. %LIDn } )
Returns a list of all libraries currently installed on your '48.
Note: We didn't use the '?' postfix because normally it marks a routine
for returning a flag in RPL. The JARGON file, v2.9.9, 01 APR 1992 states:
3. The `-P' convention: Turning a word into a question by
appending the syllable `P'; from the LISP convention of appending
the letter `P' to denote a predicate (a boolean-valued function).
The question should expect a yes/no answer, though it needn't.
At dinnertime:
Q: "Foodp?"
A: "Yeah, I'm pretty hungry." or "T!"
At any time:
Q: "State-of-the-world-P?"
A: (Straight) "I'm about to go home."
A: (Humorous) "Yes, the world has a state."
so we used 'p' for marking routines returning information ;-)
fEVAL ( ob --> ? )
Works like EVAL, but switches the display off first. Speeds up evaluation
by ~11%. In case of an error or the ob has finished execution, the
display is switched on again. Not very useful, if ob prompts for input..
3.5 Things to Notice
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
úÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
3 HP 48 Resource Allocation Guideline: Library ID's 3
~AÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ'
3 0000 - 0256 Take-over libraries; do not use! 3
3 0257 - 0512 HP ROM-based libraries; do not use! 3
3 0513 - 0768 HP RAM-based libraries; do not use! 3
3 0769 - 1791 3rd Party (assigned by HP) 3
3 1792 - 2047 Command-line; do not use! 3
àÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄù
[This sure doesn't seem to leave many for us hackers to use, eh? -jkh-]
*Don't use the following LIDs*, they're handled special by a '48SX (and
probably also by a GX):
LID What's special ?
ÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
240-255 ROMPTR@ assumes that the associated library command is in the
hidden ROM.
0-256,1792 The central routine to compile IDs (PTR 7BFD on a SX, PTR
7C18 on a GX) returns pointer instead of XLIBs.
The library stucture is 'flat', so don't try to include subdirectories in a
library, it can end up in a memory lost.
Not all program objects that execute correctly from global variables are
directly convertable into libraries. Here are some pitfalls:
- Since a library cannot be modified, no library command may be the
target of a STO or PUT operation.
- XLIB names are not usable in all contexts in which global names are
valid arguments. This can cause constructs that reference a named
object to fail. For example,
'A' 5 GETI
where A is a list will not work when A is converted to an XLIB name.
Instead use
A 5 GETI
- XLIB names are not valid as formal variables in algebraics, or as the
independent variable for plotting or solving.
- \->STR applied to a global name that is converted to a 'hidden' library
command (see $HIDDEN) returns a null string.
If any visible command starts with the seqence '\<< \->' or '\->' it's marked
in the library as a valid command for algebraics. If you press its associated
softkey in ALG entry mode, you'll get 'name()'.
Multiple occurences of variable names results in an incorrect library because
only the contents of the first one is picked up.
D->LIB needs ~(1.2 * size_of_source_directory) bytes to be free to generate a
library.
The time D->LIB needs for doing a job depends mainly on the total number of
commands included in the resulting library. Eg. Raymond runs D->LIB on a
~60kb directory containing ~300 variables; D->LIB needs ~15min on a rev A
'48 to make the library (not in FAST-mode). Of course, this is quite faster
than using USRLIB.EXE !!!
Reassembling a split library may be dangerous if the original library was
not generated using USRLIB.EXE or D->LIB. There is no guarantee that the
result will work properly - even if no code changes are done.
USRLIB.EXE generates a link table entry for the configuration program; if you
split such a library with L->DIR, you'll get the configuration code twice,
the first one stored in $CONFIG, the second one stored in a variable of the
generated directory. Purge the variable before using D->LIB. You also can
use LIBp to see the second reference to the config code.
Appendix A - Quick Reference Guides
ííííííííííííííííííííííííííííííííííí
A.1 <-RPL->
ÄÄÄÄÄÄÄÄÄÄÄ
A.1.1 Commands
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Page 1234.1
RPL-> ( ob --> $ ) decompile object
->RPL ( $ --> ob ) compile object
DCADR ( hxs --> $ hxs' ) decompile one word
COD-> ( code --> $ ) disassemble CODE
->COD ( $ --> code libdat ) assemble CODE
->OB ( ob --> ob' ) convert object
Page 1234.2
DAN ( hxs %n --> $1 .. $n hxs' ) disassemble n times
DA1 ( hxs --> $ hxs' ) disassemble one mnemo
DAXY ( hxs hxs --> $ ) disassemble block
SYM-> ( libdat --> $ ) convert symbol table
$-> ( $ --> ob ) hex-dump to object
->$ ( ob --> $ ) object to hex-dump
Page 1234.3
EC ( --> ? ) entries catalog
E<->A ( hxs | $name --> $name | hxs ) get name/address
RPLtab ( --> $ ) recall ref. table
4/5/7 ( --> ) sys-stack display
CC ( --> ? ) character set catalog
A.1.2 Flag Usage
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
General:
Flag Meaning
ÄÄÄÄ ÄÄÄÄÄÄÄ
-4 If set, RPL->/DCADR are using the disassembler to decompile
code objects.
-13 Quiet mode if set. The status report of RPL->, ->RPL, COD->
and ->COD is suppressed.
64 Reserved.
63 Toggles sys-stack between 5/7 lines mode.
62 Set by 4/5/7 to signal an active medium font display. Can
be cleared to quit the sys-stack.
61 Toggles the behaivior of the down arrow key during sys-stack
display, the EDIT menu key during the sys-i-stack and the
ENTER key when finishing a command line. If set, you can edit
objects in sys-RPL syntax. A menu toggle for this flag can be
found on the 3rd page of the i-stack menu (labeled S-ED).
DAN and DA1 are using the following flags:
Flag (set) Meaning
ÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄ
1 next instr is a GO/RET YES/NO
2 last instr was RET...
3 last instr was GO C/NC/TO
4 last instr was relative GOSUB
5 last instr was absolute GO
6 last instr was PC manipulation
7 used internaly
8 last instr was absolute GO or Dx=(5)
A.1.3 Error Messages
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
General Errormessages:
"Undefined XLIB Name"
Requests to execute a command when the <-RPL-> library is not attached
to the HOME directory will cause this error. See section 1.3.
"Need Binary Number"
The object passed to DCADR or DA1 isn't a binary number.
"Need String"
The object passed to ->RPL, ->COD or $-> isn't a string.
"Data Modifies Stack"
The object stored in RPL.TAB or ECpar doesn't add one item to the
stack.
"Where's your Program ?"
The string passed to ->RPL results to nothing.
"Primitive Code Object"
The object passed to RPL-> or the address passed to DCADR points to
a PCO.
"Found ACPTR on a SX"
RPL-> can't decompile ACPTR (ie. EXT1 objects) if <-RPL-> is installed
on a '48SX.
->COD Errormessages:
->COD generates error messages of the following form:
"->COD Error: x:yy
Message"
where 'x' is the INCLUDE nesting depth and 'yy' is the character offset of
the first character following the token that caused the error. 'Message'
may be one of the following:
"ENDIF Expected" an IF isn't matched by an ENDIF
"ENDIF w/o IF" missplaced ENDIF
"ELSE w/o IF" missplaced ELSE
"Invalid Parameter" invalid parameter field
"Inv. Expr: expr" invalid parameter field expression <expr>
"Invalid Mnemonic" invalid menemonic
"Duplicate Label" double defined label
"GOYES/RTNYES Expected" comparisation without a following
conditional jump
"GOYES out of range" jump destination is more than -128/+127
nibbles away
"Parameter Expected" parameter of a mnemonic which expects
one is missing
"Unknown Symbol: symb" unknown symbol <symb> in an expression
"Inv. $: str" invalid string <str> constant
"No IF Nesting Yet" nesting of conditional IF .. ELSE .. ENDIF
structures is not allowed (yet)
"Can't INCLUDE: nam"
There's no variable with the name <nam>
->RPL Errormessages:
->RPL generates error messages of the following form:
"->RPL Error: x:yy
Message"
where 'x' is the INCLUDE nesting depth and 'yy' is the character offset of
the first character following the token that caused the error. Note that
if the error is generated by the asssembler (called by ->RPL to assemble
inline code), 'yy' is the error position relative to the first char after
the CODE or ASSEMBLE token. 'Message' may be one of the following
(additional to the ones listed for ->COD):
") Expected"
Missing a ) to terminate a comment
"" Expected"
Missing a " to terminate a string
"ENDCODE Expected"
Missing the token ENDCODE to terminate a CODE statement
"RPL Expected"
Missing the token RPL to terminate a ASSEMBLE statement
"Misplaced ; or }"
Found a ; or } without a opening ::, {, UNIT or SYMBOL
"Suspect %"
"Suspect %%"
Parsing of a number results in an object of incorrect type
"Body Len <> Datalen"
The length field of a HXS-like styled statement is not equal to
the data length
"ACPTR is a G object"
ACPTR can only be compiled, if <-RPL-> is installed on a GX
"EXT1 is a S object"
EXT1 can only be compiled, if <-RPL-> is installed on a SX
"More Tokens Expected"
The statement at the end of the input string is incomplete
In the following messages 'ttt' represents the token that causes the
error:
"ROMP LibID >FFF: ttt"
"ROMP ROMWD >FFF: ttt"
The library ID part or the ROM word number part of a ROMPTR statement
is > FFF
"Suspect \ Seq: ttt"
The escape sequence ttt in the string, ID or LAM is incomplete or
invalid
"Can't INCLUDE: ttt"
"Can't INCLOB: ttt"
There's no variable with the name ttt
"Cont. no $: nam"
The INCLUDEd variable <nam> doesn't contain a string
"Inv. xxx: ttt"
where 'xxx' is one of the following:
"Tok" - ttt is unresolvable
"#" - ttt is out of range or contains chars other than hex digits
"$" - ttt doesn't start with a "
"%","%%"- ttt represents an invalid number
"PTR" - ttt is out of range or contains chars other than hex digits
"CHR" - ttt contains more than one char
"Body Dat" - the data field of a HXS-like styled statement contains
chars other than hex digits
"Body len" - the length field of a HXS-like styled statement contains
chars other than hex digits
"RomWd" - the ROM word number field of a ROMPTR is longer than 5
chars or contains chars other than hex digits
"LibID" - the library ID field of a ROMPTR is longer than 5 chars
or contains chars other than hex digits
"APaa" - the access address field of an ACPTR is longer than 5
chars or contains chars other than hex digits
"APda" - the data address field of an ACPTR is longer than 5
chars or contains chars other than hex digits
A.2 <-LIB->
ííííííííííí
A.2.1 Commands
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Page 1221.1
D->LIB ( --> lib ) build library
L->DIR ( % --> dir ) split library
MCFG ( --> ) make config program
ML->D ( --> prg ) make libdat-> handler
MD->L ( --> prg ) make ->libdat handler
OB-> ( ob --> ? ) split object
Page 1221.2
->DIR ( meta(ob,id) --> dir ) make directory
->PRG ( meta(ob) --> prg ) make program
->XLIB ( % % | # # --> xlib ) make XLIB
->ARR ( meta(ob) --> arry ) make array
->ALG ( meta(ob) --> alg ) make algebraics
->LD ( {} % --> libdta ) make library data
Page 1221.3
->BAK ( ob $ --> bak ) make backup
->ID ( $ --> id ) make identifier
ADRp ( ob --> ob # ) get address of object
$romid ( --> id ) get id '$ROMID'
$visible ( --> id ) get id '$VISIBLE'
$title ( --> id ) get id '$TITLE'
Page 1221.4
$config ( --> id ) get id '$CONFIG'
$vars ( --> id ) get id '$VARS'
$hidden ( --> id ) get id '$HIDDEN'
$message ( --> id ) get id '$MESSAGE'
LBCRC ( lib | bak --> lib' | bak' ) recalculate CRC
RNLIB ( lib $ --> lib' ) rename library
Page 1221.5
CHLID ( lib % --> lib' ) change LID
RHASH ( % --> C# ) get hash table
RLINK ( % --> C# ) get link table
RCFG ( % --> prg ) get config code
RMSG ( % --> arry ) get message table
RTITLE ( % --> $ ) get title
Page 1221.6
RPORT ( % --> ob ... ) recall port
RLIB ( % --> lib % ... ) recall library(s)
PGLIB ( % | :%:% --> ) purge library
STLIB ( lib % --> ) store library
ACLIB ( :%:% --> ) activate library
LIBp ( % --> $ ) get library layout
Page 1221.7
INSTp ( --> {} ) get installed LIDs
LIBSp ( --> {} ) get all LIDs on 48
fEVAL ( ob --> ? ) fast EVAL
A.2.2 Flag Usage
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
5 Set: STLIB executes config code of passed library after
installation.
ACLIB executes config code of activated library.
<-LIB->s config code displays a (c) notice.
Clear: STLIB and ACLIB are simply attaching the handled library
to the HOME directory.
<-LIB->s config code doesn't display (c) notice.
6 Set: L->DIR places the $control variables at the end of the
generated directory.
Clear: L->DIR places the $control variables at the beginning of
the generated directory.
7 Set: L->DIR generates a $HIDDEN but no $VISIBLE variable.
Clear: L->DIR generates a $VISIBLE but no $HIDDEN variable.
-13 Set: D->LIB/L->DIR switch the display off while processing
a directory/library (fast mode).
Clear: D->LIB/L->DIR are leaving the display on while working.
A.2.3 Error Messages
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
"Missing $ROMID"
$ROMID is not defined in the current directory
"$ROMID Not Real/Binary"
$ROMID doesn't contain a % or HXS object
"$ROMID Out of Range"
a) the value of $ROMID is > 2047
b) a % > 2047 was passed to CHLID
"$CONFIG Not a Program"
Because the stack must not change during warmstarts, $CONFIG must contain
a program
Note: Use 1 ->PRG to embedd CODE, IDs or XLIBs into a program.
"$HIDDEN Not a List"
"$VISIBLE Not a List"
"$VARS Not a List"
"$MESSAGE Not a List"
$XXX must contain a list
"Found ID Name>16 Chars"
D->LIB have found a visible command name which is > 16 chars in size
"Found 0-ID"
D->LIB have found a visible command name with the size 0
"Won't work on a G"
The initiated operation can't be executed on a '48G(X).
Appendix B - A ->COD Example
íííííííííííííííííííííííííííí
Key in the following text (including the string delimiters) on your '48 (you
may leave out the comments):
" GOSBVL =SAVPTR ** Save RPL pointers in save locations
** P is 0 , HEX mode enabled
LAHEX 123AFE ** Load HEX nibbles into A Register
** starting at P
P= 5 **
GOVLNG =PUSHhxsLoop ** Push A[WP] onto Data stack
** and pass control to RPL
"
Store it in the variable SRC1. Recall the text to the stack, then press
[->COD]. The display will show 'ASSEMBLER PASS 1' on the bottom line. In the
upper part of the display 'Line nnn' will appear, where <nnn> represents
the actual code line to be assembled (empty lines or comment lines are not
counted).
A second later the display will show 'ASSEMBLER PASS 2' on the bottom line
and 'Processing nnn Lines' in the message area. Another second later the
source will have been assembled and the the string will be replaced by a
'Code' object and a 'Library Data' object. The stack should look as follows:
úÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
3 3
~AÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ'
34: 3
33: 3
32: Code3
31: Library Data3
3## ### ### ### ### ##3
àÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄù
The Library Data object contains all used local symbols (eg. labels). For the
above example, it is an empty string, as there are no local symbols. The Code
object represents the assembled source text. DROP the Library Data object and
store the Code object into 'XQ1', then press the menu key [XQ1] . The stack
now looks like:
úÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
3 3
~AÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ'
34: 3
33: 3
32: 3
31: # 123AFEh3
3## ### ### ### ### ##3
àÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄù
Now lets change example 1 to make use of the symbolic facilities of SASM48.
First recall [SRC1] and edit the string:
"
hexdig EQU #123AFE
pHXS EQU 5
GOSBVL =SAVPTR ** Save RPL pointers in save locations
** P is 0 , HEX mode enabled
LA(6) hexdig ** Load 6 HEX nibbles (represented by hexdig)
** into A Register , starting at P
P= pHXS ** Set P to the value specified by pHXS
GOVLNG =PUSHhxsLoop ** Push A[WP] onto Data stack
** and pass control to RPL
"
Store the string in SRC2, recall it back to the stack, then press [->COD].
The result looks like the result of example 1 except that the Library Data
now contains the values of the defined labels. When the stack shows:
úÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
3 3
~AÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ'
34: 3
33: 3
32: Code3
31: Library Data3
3## ### ### ### ### ##3
àÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄù
press [SYM->] (located on the second menu page). The display changes to:
úÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
3 3
~AÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ'
34: 3
33: 3
32: Code3
31: "hexdig EQU #..3
3## ### ### ### ### ##3
àÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄù
Press the down-arrow key:
úÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
3 prg3
~AÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ'
3 3
3 3
3"hexdig EQU #123..3
3pHXS EQU #5 3
3## ### ### ### ### ##3
àÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄù
This is the symbol table for SRC2. Press ATTN to return to the stack. DROP
the string in level 1 and store the Code object into 'XQ2'. Press [XQ2]. You
will get the same result as in example 1 because it's the same machine
language program.
You could even use [COD->] to disassemble the Code object in level 1.
Appendix C - Ordering Information
ííííííííííííííííííííííííííííííííí
The sources of the <-RPL-> and the <-LIB-> libraries consists of more than
18000 lines of RPL/assembler code (that's more than 300kb of text !) and we
have spent our free time for more than two years in writing RPL48, so we
decided to release this version as GiftWare - ie. you can use RPL48 as long
as you like but only for developing non-comercial software and only as a
private person.
If you think RPL48 is useful and that the authors deserve to be rewarded for
the time they have invested in developing this toolkit, feel free to send
one of us (or both ;-) any sort of gift (even only a postcard will be
welcome).
If your gift covers the expense sending you a disk via SnailMail (costs
are: the disk, an envelope, the stamp and our time -> ~$25 or something
equivalent), we will send you the latest *whole* version of RPL48 on a
MesS-DOS formatted disk (including the <-RPL-> library branded with your
name in the startup message). Don't forget to include your name, address
and the disk size you prefer.
Developping commercial software using RPL48 requires registration via the
GiftWare concept; companies must send us at least a $50-worth gift for
registration.
Planned for the future are:
- better ARRY support in <-RPL->
- maybe a DIR support in <-RPL->
- a built-in system RPL debugger (hairy)
- a string editor (hairy)
- better GX port of <-LIB->
(all without guaranteeing the implementation)
Contact addresses:
Detlef Mueller
Bellerbek 33
D-22559 Hamburg
Germany
Tel: +49 40 811 92 80 8:00pm - 0:00am CET + 1h ds
FAX: +49 40 589 58 199
e-mail: detlef@dmhh.hanse.de
Raymond Hellstern
Liebigstr. 8
D-30163 Hannover
Germany
Tel./FAX +49 511 66 10 11